<html><head><meta charset="utf-8"/><title>Objects</title></head><body><h1>Objects</h1><div class="x-wiki-content x-main-content">
 <p>
  和
  <code>
   Array
  </code>
  类似，underscore也提供了大量针对Object的函数。
 </p>
 <h3>
  keys / allKeys
 </h3>
 <p>
  <code>
   keys()
  </code>
  可以非常方便地返回一个object自身所有的key，但不包含从原型链继承下来的：
 </p>
 <pre><code>'use strict';

function Student(name, age) {
    this.name = name;
    this.age = age;
}

var xiaoming = new Student('小明', 20);
_.keys(xiaoming); // ['name', 'age']
</code></pre>
 <p>
  <code>
   allKeys()
  </code>
  除了object自身的key，还包含从原型链继承下来的：
 </p>
 <pre><code>'use strict';

function Student(name, age) {
    this.name = name;
    this.age = age;
}
Student.prototype.school = 'No.1 Middle School';
var xiaoming = new Student('小明', 20);
_.allKeys(xiaoming); // ['name', 'age', 'school']
</code></pre>
 <h3>
  values
 </h3>
 <p>
  和
  <code>
   keys()
  </code>
  类似，
  <code>
   values()
  </code>
  返回object自身但不包含原型链继承的所有值：
 </p>
 <pre><code>'use strict';

var obj = {
    name: '小明',
    age: 20
};

_.values(obj); // ['小明', 20]
</code></pre>
 <p>
  注意，没有
  <code>
   allValues()
  </code>
  ，原因我也不知道。
 </p>
 <h3>
  mapObject
 </h3>
 <p>
  <code>
   mapObject()
  </code>
  就是针对object的map版本：
 </p>
 <pre><code>'use strict';

var obj = { a: 1, b: 2, c: 3 };
// 注意传入的函数签名，value在前，key在后:
_.mapObject(obj, (v, k) =&gt; 100 + v); // { a: 101, b: 102, c: 103 }
</code></pre>
 <h3>
  invert
 </h3>
 <p>
  <code>
   invert()
  </code>
  把object的每个key-value来个交换，key变成value，value变成key：
 </p>
 <pre><code>'use strict';

var obj = {
    Adam: 90,
    Lisa: 85,
    Bart: 59
};
_.invert(obj); // { '59': 'Bart', '85': 'Lisa', '90': 'Adam' }
</code></pre>
 <h3>
  extend / extendOwn
 </h3>
 <p>
  <code>
   extend()
  </code>
  把多个object的key-value合并到第一个object并返回：
 </p>
 <pre><code>'use strict';

var a = {name: 'Bob', age: 20};
_.extend(a, {age: 15}, {age: 88, city: 'Beijing'}); // {name: 'Bob', age: 88, city: 'Beijing'}
// 变量a的内容也改变了：
a; // {name: 'Bob', age: 88, city: 'Beijing'}
</code></pre>
 <p>
  注意：如果有相同的key，后面的object的value将覆盖前面的object的value。
 </p>
 <p>
  <code>
   extendOwn()
  </code>
  和
  <code>
   extend()
  </code>
  类似，但获取属性时忽略从原型链继承下来的属性。
 </p>
 <h3>
  clone
 </h3>
 <p>
  如果我们要复制一个object对象，就可以用
  <code>
   clone()
  </code>
  方法，它会把原有对象的所有属性都复制到新的对象中：
 </p>
 <pre><code class="language-x-javascript">'use strict';
var source = {
    name: '小明',
    age: 20,
    skills: ['JavaScript', 'CSS', 'HTML']
};
----
var copied = _.clone(source);
----
console.log(JSON.stringify(copied, null, '  '));
</code></pre>
 <p>
  注意，
  <code>
   clone()
  </code>
  是“浅复制”。所谓“浅复制”就是说，两个对象相同的key所引用的value其实是同一对象：
 </p>
 <pre><code>source.skills === copied.skills; // true
</code></pre>
 <p>
  也就是说，修改
  <code>
   source.skills
  </code>
  会影响
  <code>
   copied.skills
  </code>
  。
 </p>
 <h3>
  isEqual
 </h3>
 <p>
  <code>
   isEqual()
  </code>
  对两个object进行深度比较，如果内容完全相同，则返回
  <code>
   true
  </code>
  ：
 </p>
 <pre><code>'use strict';

var o1 = { name: 'Bob', skills: { Java: 90, JavaScript: 99 }};
var o2 = { name: 'Bob', skills: { JavaScript: 99, Java: 90 }};

o1 === o2; // false
_.isEqual(o1, o2); // true
</code></pre>
 <p>
  <code>
   isEqual()
  </code>
  其实对
  <code>
   Array
  </code>
  也可以比较：
 </p>
 <pre><code>'use strict';

var o1 = ['Bob', { skills: ['Java', 'JavaScript'] }];
var o2 = ['Bob', { skills: ['Java', 'JavaScript'] }];

o1 === o2; // false
_.isEqual(o1, o2); // true
</code></pre>
 <p>
  更多完整的函数请参考underscore的文档：
  <a href="http://underscorejs.org/#objects">
   http://underscorejs.org/#objects
  </a>
 </p>
</div>
</body></html>